﻿package  
{
	import Box2D.Collision.b2AABB;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2World;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.utils.getTimer;
	
	/**
	 * ...
	 * @author Georg Kamptner
	 */
	public class GameBodyDragable extends Sprite implements IGameBody
	{
		// -- variables & attributes ---------------------------------------------------------------------------
		protected var _body:b2Body;
		protected var _player:Player;
		public var _creation_time:uint;
		protected var _game:Game;
		protected var _mouse_x:int = 0; // needed for velocity calculations while dragging
		protected var _mouse_y:int = 0; // needed for velocity calculations while dragging
		protected var _current_mouse_speed_delay:uint = 0;
		protected var _mouse_speed_delay_in_frames:uint = 10; // the number of frames which are considered in the drag n drop mouse speed calculation (aka throwing)
		protected var _velocity_multiplier:uint = 12;
		protected var _asset:DisplayObjectContainer;
		protected var _wincheck_count:int = 0;
		
		// -- getter & setter ----------------------------------------------------------------------------------
		public function get body():b2Body { return _body; }
		
		public function set body(value:b2Body):void 
		{
			_body = value;
		}
		
		public function get player():Player { return _player; }
		
		public function set player(value:Player):void  
		{
			_player = value;
		}
		
		public function get wincheck_count():int { return _wincheck_count; }
		
		public function set wincheck_count(value:int):void 
		{
			_wincheck_count = value;
			//(_asset.getChildByName("wincheck_count_txt") as TextField).text = "" + value;
		}
		
		// -- constructor --------------------------------------------------------------------------------------
		public function GameBodyDragable(body:b2Body, game:Game, asset_class:Class) 
		{
			_body = body;
			_creation_time = getTimer();
			_game = game;
			_asset = new asset_class();
			addChild(_asset);
		}
		
		// -- methods ------------------------------------------------------------------------------------------
		public function enableDragAndDrop():void
		{
			Sprite(_body.m_userData).buttonMode = true;
			_body.m_userData.addEventListener(MouseEvent.MOUSE_DOWN, onStartDrag);
		}
		
		public function disableDragAndDrop():void
		{
			Sprite(_body.m_userData).buttonMode = false;
			Sprite(_body.m_userData).useHandCursor = false;
			_body.m_userData.removeEventListener(MouseEvent.MOUSE_DOWN, onStartDrag);
		}
		
		private function onStartDrag(e:MouseEvent):void 
		{
			if (_game.is_paused) return;
			
			_body.m_userData.addEventListener(Event.ENTER_FRAME, onDrag);
			_game.stage.addEventListener(MouseEvent.MOUSE_UP, onStopDrag);
			_game.stage.mouseX;
			_mouse_x = _game.stage.mouseX;
			_mouse_y = _game.stage.mouseY;
		}
		
		
		/*
		private function onDrag(e:Event):void 
		{
			// view
			_body.m_userData.x = _game.stage.mouseX;
			_body.m_userData.y = _game.stage.mouseY;
			// b2d
			var vx:int = _game.stage.mouseX - _mouse_x;
			var vy:int = _game.stage.mouseY - _mouse_y;
			_mouse_x = _game.stage.mouseX;
			_mouse_y = _game.stage.mouseY;
			_game.world.updateBodyPositionInPixels(_body, _game.stage.mouseX, _game.stage.mouseY, vx*10, vy*10); // 10 is some Speed Multilier
		}
		*/
		
		
		private function onDrag(e:Event):void 
		{
			if (_game.is_paused) return;
			
			// view
			var players : int = 2; //_game.players.size()
			var width : int = _game.stage.stageWidth;
			
			// calc velocity
			var vx:int = _game.stage.mouseX - _mouse_x;
			var vy:int = _game.stage.mouseY - _mouse_y;
			if (_current_mouse_speed_delay++ > _mouse_speed_delay_in_frames)
			{
				_mouse_x = _game.stage.mouseX;
				_mouse_y = _game.stage.mouseY;
			}
			
			if( _game.isPlayerAllowedToExecuteAction() )
			{
				// update body position
				_body.m_userData.x = _game.stage.mouseX;
				_body.m_userData.y = _game.stage.mouseY;
				// update velocity & position
				_game.world.updateBodyPositionInPixels(_body, _game.stage.mouseX, _game.stage.mouseY, vx * _velocity_multiplier, vy * _velocity_multiplier); // 10 is some Speed Multilier
			}
			else
			{
				_body.m_userData.x = _game.stage.mouseX;
				_body.m_userData.y = _game.stage.mouseY;
				_mouse_x = ((width/players)*(player.id+1)-(width/players)*(player.id));
				_mouse_y = _game.stage.mouseY;
				_game.world.updateBodyPositionInPixels(_body,_mouse_x, _game.stage.mouseY, -vx * 2, -vy * 2);
				
				// add to opposite player, is done automatically by the GameWorld onEnterFrame
				 
				// stop dragging
				onStopDrag();
			}
		}
		
		
		public function updatePlayerOwner(id:int): void
		{
			if (player.id != id)
			{
				_game.addBodyToOppositePlayer(_player.id, this);
			}
		}
		
		
		private function onStopDrag(e:MouseEvent = null):void 
		{
			if (_game.is_paused) return;
			
			_body.m_userData.removeEventListener(Event.ENTER_FRAME, onDrag);
			_game.stage.removeEventListener(MouseEvent.MOUSE_UP, onStopDrag);
			
			_game.executeActionOnCurrentPlayer();
		}
		
		public function changeAssetTo(asset_class:Class):void
		{
			removeChild(_asset);
			_asset = new asset_class();
			addChild(_asset);
		}
		
		public function destroy():void
		{
			_body.m_userData.removeEventListener(Event.ENTER_FRAME, onDrag);
			_game.stage.removeEventListener(MouseEvent.MOUSE_UP, onStopDrag);
			
			disableDragAndDrop();
			_mouse_x = 0;
			_mouse_y = 0;
			//_creation_time = 0;
			_game.world.removeBox(_body);
			_body = null;
			_game = null;
		}
		
	}
	
}